#!/bin/bash
set -e

# When this script is spawned by Electron (or the PKG installer), the child
# PATH is the minimal /usr/bin:/bin:/usr/sbin:/sbin — `/usr/local/bin` is
# NOT inherited from the user's login shell. We symlink `docker` into
# `/usr/local/bin/` below and then poll `docker --version`; that lookup
# silently fails without this line.
export PATH="/usr/local/bin:$PATH"

LOG_FILE="/tmp/postinstall.log"
: > "$LOG_FILE"
exec > >(tee -a "$LOG_FILE") 2>&1

APP_NAME="OpenGPU Provider Suite.app"
APP_PATH="/Applications/$APP_NAME"
DOCKER_CLI="/usr/local/bin/docker"
TIMEOUT=30
INTERVAL=2
SECONDS_WAITED=0

# Exit code legend (kept stable so the Electron wrapper can map them):
#   0   success
#   2   osascript / privileged install failed
#   3   Docker.app missing after install attempt
#   4   Docker CLI never became available
#   5   Docker DMG could not be mounted
#   6   Docker DMG could not be downloaded
#   130 user cancelled the admin prompt

fail() {
    local code="$1"
    shift
    echo "❌ $*"
    echo "❌ exit_code=$code"
    exit "$code"
}

echo "📦 Starting OpenGPU Provider Suite postinstall..."

if [[ -d "/Applications/Docker.app" ]]; then
    echo "✅ Docker Desktop is installed."
else
    echo "📦 Docker Desktop not found. Installing..."

    echo "📦 Copying Docker.app and cleaning old Docker files..."


    ARCH=$(uname -m)
    if [[ "$ARCH" == "arm64" ]]; then
        DOCKER_URL="https://desktop.docker.com/mac/main/arm64/Docker.dmg"
    else
        DOCKER_URL="https://desktop.docker.com/mac/main/x86_64/Docker.dmg"
    fi

    if [[ -f "/tmp/Docker.dmg" ]]; then
        echo "📂 Using existing /tmp/Docker.dmg..."
        DOCKER_DMG="/tmp/Docker.dmg"
    else
        echo "⬇️ Downloading Docker Desktop from $DOCKER_URL ..."
        if ! curl -fL --retry 3 --retry-delay 2 "$DOCKER_URL" -o /tmp/Docker.dmg; then
            fail 6 "Failed to download Docker Desktop from $DOCKER_URL. Check your internet connection or try again later."
        fi
        DOCKER_DMG="/tmp/Docker.dmg"
    fi

    if [[ ! -s "/tmp/Docker.dmg" ]]; then
        fail 6 "Downloaded Docker.dmg is empty or missing at /tmp/Docker.dmg."
    fi

    echo "📂 Mounting DMG..."
    MOUNT_POINT=$(hdiutil attach /tmp/Docker.dmg -nobrowse | grep -Eo '/Volumes/Docker.*' || true)

    if [[ -z "$MOUNT_POINT" ]]; then
        fail 5 "Failed to mount /tmp/Docker.dmg. The file may be corrupted — delete it and retry."
    fi
    echo "Please enter your password if prompted to allow installation."
result=$(osascript <<EOC
    try
        do shell script "echo Starting Docker installation... && \
        rm -rf /Applications/Docker.app && \
        rm -rf /usr/local/bin/hub-tool && \
        rm -rf /usr/local/bin/compose-bridge && \
        rm -rf /usr/local/bin/kubectl.docker && \
        rm -rf /usr/local/cli-plugins/docker-compose && \
        rm -rf /usr/local/bin/docker-credential-desktop && \
        rm -rf /usr/local/bin/docker-machine && \
        rm -rf /usr/local/bin/docker-compose && \
        rm -rf /usr/local/bin/docker-credential-osxkeychain && \
        rm -rf ~/.docker && \
        rm -rf /usr/local/bin/docker-credential-ecr-login && \
        rm -rf /usr/local/bin/docker* && \
        cp -R -X \"$MOUNT_POINT/Docker.app\" /Applications/ && \
        ln -sf /Applications/Docker.app/Contents/Resources/bin/docker /usr/local/bin/docker && \
        ln -sf /Applications/Docker.app/Contents/Resources/bin/docker-compose /usr/local/bin/docker-compose && \
        ln -sf /Applications/Docker.app/Contents/Resources/bin/docker-credential-desktop /usr/local/bin/docker-credential-desktop && \
        ln -sf /Applications/Docker.app/Contents/Resources/bin/docker-credential-osxkeychain /usr/local/bin/docker-credential-osxkeychain && \
        ln -sf /Applications/Docker.app/Contents/Resources/bin/docker-credential-ecr-login /usr/local/bin/docker-credential-ecr-login" with administrator privileges
    on error errMsg number errNum
        if errNum = -128 then
            return "CANCELLED"
        else
            return "ERROR:" & errMsg
        end if
    end try
EOC
)

    if [ "$result" = "CANCELLED" ]; then
        echo "User cancelled the administrator prompt."
        hdiutil detach "$MOUNT_POINT" -quiet 2>/dev/null || true
        exit 130
    elif [[ "$result" == ERROR:* ]]; then
        hdiutil detach "$MOUNT_POINT" -quiet 2>/dev/null || true
        fail 2 "Privileged install step failed: ${result#ERROR:}"
    fi

    echo "✅ Docker.app copied to /Applications."
    echo "💿 Unmounting DMG..."
    hdiutil detach "$MOUNT_POINT" -quiet || true
    echo "✅ DMG unmounted from $MOUNT_POINT"
    echo "🔗 Creating Docker CLI symlink..."

fi

if [[ ! -d "/Applications/Docker.app" ]]; then
    fail 3 "Docker.app is not in /Applications after the install step. Installation did not complete."
fi

# Pre-write Docker Desktop settings BEFORE first launch so it does not
# prompt for Rosetta 2 installation on Apple Silicon. We ship an arm64
# provider stack and only intend to run arm64 workloads — amd64 emulation
# via Rosetta is unnecessary and would trigger an install dialog the user
# has to click through. Docker Desktop 4.34+ uses `settings-store.json`;
# older versions use `settings.json`. Only write if the file doesn't yet
# exist so we never clobber a user's manual choice on a re-install.
DOCKER_GROUP_DIR="$HOME/Library/Group Containers/group.com.docker"
mkdir -p "$DOCKER_GROUP_DIR"
for SETTINGS_FILE in "settings-store.json" "settings.json"; do
    TARGET="$DOCKER_GROUP_DIR/$SETTINGS_FILE"
    if [ ! -f "$TARGET" ]; then
        # Note on what we can and cannot skip on first launch:
        #  * Rosetta prompt   → skippable via UseVirtualizationFrameworkRosetta=false
        #  * Welcome / tour   → skippable via ShowedWelcomeSurvey=true + OnboardingCompleted=true
        #  * Telemetry opt-in → skippable via AnalyticsEnabled=false
        #  * SLA acceptance   → NOT skippable; Docker requires interactive Accept
        #  * Local Network permission → NOT skippable; macOS TCC prompt
        # We pre-write the ones we can. Keys are duplicated in old (camelCase)
        # and new (PascalCase) forms so both Docker versions read them.
        cat > "$TARGET" <<'JSON'
{
  "UseVirtualizationFramework": true,
  "UseVirtualizationFrameworkRosetta": false,
  "useVirtualizationFrameworkRosetta": false,
  "AnalyticsEnabled": false,
  "analyticsEnabled": false,
  "ShowedWelcomeSurvey": true,
  "showedWelcomeSurvey": true,
  "OnboardingCompleted": true,
  "onboardingCompleted": true,
  "OpenUIOnStartupDisabled": true,
  "openUIOnStartupDisabled": true,
  "DisableUpdate": true,
  "disableUpdate": true
}
JSON
        echo "🛠️  Wrote Docker settings to skip Rosetta + welcome tour + telemetry: $TARGET"
    fi
done

echo "🚀 Starting Docker Desktop..."
open -a /Applications/Docker.app

# Poll for the CLI binary using an absolute path — `docker --version` via
# PATH would fail even when the symlink exists if this subprocess's PATH
# didn't already include /usr/local/bin. We also just check for the file
# rather than executing it, because on a brand-new install Docker Desktop
# shows a license dialog before the daemon starts; the CLI symlink is
# there instantly but `docker version` (needs daemon) can hang for
# minutes waiting for the user to click Accept.
while [ ! -x "$DOCKER_CLI" ]; do
    sleep $INTERVAL
    SECONDS_WAITED=$((SECONDS_WAITED + INTERVAL))
    if [ $SECONDS_WAITED -ge $TIMEOUT ]; then
        break
    fi
done

if [ -x "$DOCKER_CLI" ]; then
    # Best-effort version print; if the daemon isn't up yet this is fine.
    VERSION_OUT=$("$DOCKER_CLI" --version 2>/dev/null || echo "not ready yet")
    echo "✅ Docker CLI symlink ready: $VERSION_OUT"
else
    # Not a hard failure — Docker.app is installed and launched. The
    # Electron app's own suite-start flow polls for daemon readiness
    # separately, and will surface a friendlier message if the user
    # hasn't accepted the license yet.
    echo "⚠️  Docker CLI symlink was not found after ${TIMEOUT}s at $DOCKER_CLI."
    echo "⚠️  Docker Desktop may still be finishing its first-launch setup."
    echo "⚠️  Accept the license/EULA in the Docker Desktop window, then"
    echo "⚠️  return to OpenGPU Provider Suite — installation will resume."
fi

echo "🚀 Launching Docker Desktop..."

echo "🎉 OpenGPU Provider Suite Docker installation completed."
